package com.alibaba.citrus.cr.sales.plan.facade.service.statistics.stat;

import com.alibaba.citrus.cr.common.util.SpringContextUtil;
import com.alibaba.citrus.cr.sales.plan.facade.service.SalesPlanCommonService;
import com.alibaba.citrus.cr.sales.plan.facade.service.SalesPlanOutCommonService;
import com.alibaba.citrus.cr.sales.plan.facade.service.statistics.stat.model.SalesPlanStatRequest;
import com.alibaba.citrus.cr.sales.plan.model.enums.SalesPlanStatusEnum;
import com.alibaba.citrus.cr.sales.plan.repository.ContractRepository;
import com.alibaba.citrus.cr.sales.plan.repository.SalesPlanLineRepository;
import com.alibaba.citrus.cr.sales.plan.repository.SalesPlanScItemExtendRepository;
import com.alibaba.citrus.cr.sales.plan.repository.SalesPlanScItemStatRepository;
import com.alibaba.citrus.cr.sales.plan.sdo.SalesPlanStatSDO;
import com.alibaba.citrus.cr.sales.plan.dto.api.request.MonthContractAndRollingCountResponse;
import com.alibaba.cz.base.tool.log.Log;
import com.epoch.app.bcorder.sales_plan.planscitem.service.PlanScItemService;
import com.epoch.app.bcorder.sales_plan.salesplandetail.service.SalesPlanDetailService;
import org.springframework.scheduling.concurrent.ThreadPoolTaskExecutor;
import org.springframework.util.StopWatch;

import java.util.Objects;
import java.util.concurrent.CountDownLatch;

/**
 * @author luyi
 * @date 2021/12/2 4:50 下午
 */
public abstract class SalesPlanStatAtomAbstract implements Runnable {
    private static final Log log = Log.getLogger(SalesPlanStatAtomAbstract.class);

    protected SalesPlanStatRequest statRequest;

    protected CountDownLatch latch;

    public final static SalesPlanOutCommonService salesPlanOutCommonService;
    public final static SalesPlanLineRepository salesPlanLineRepository;
    public final static ContractRepository contractRepository;
    public final static SalesPlanScItemStatRepository salesPlanScItemStatRepository;
    public final static SalesPlanScItemExtendRepository salesPlanScItemExtendRepository;
    public final static SalesPlanDetailService salesPlanDetailService;
    public final static PlanScItemService planScItemService;
    public static final ThreadPoolTaskExecutor salesPlanTaskExecutor;

    static {
        salesPlanOutCommonService = SpringContextUtil.getBean(SalesPlanOutCommonService.class);
        salesPlanLineRepository = SpringContextUtil.getBean(SalesPlanLineRepository.class);
        contractRepository = SpringContextUtil.getBean(ContractRepository.class);
        salesPlanScItemStatRepository = SpringContextUtil.getBean(SalesPlanScItemStatRepository.class);
        salesPlanScItemExtendRepository = SpringContextUtil.getBean(SalesPlanScItemExtendRepository.class);
        salesPlanDetailService = SpringContextUtil.getBean(SalesPlanDetailService.class);
        planScItemService = SpringContextUtil.getBean(PlanScItemService.class);
        salesPlanTaskExecutor = SpringContextUtil.getBean("salesPlanTaskExecutor", ThreadPoolTaskExecutor.class);
    }

    /**
     * page_size
     */
    public static final Integer CUSTOMER_ADDRESS_PAGE_SIZE = 500;


    @Override
    public void run() {
        if (statRequest == null){
            log.info("SalesPlanStatAbstract." + taskName() + ".start request is null");
            return;
        }
        log.info("SalesPlanStatAbstract." + taskName() + ".start planId:"+statRequest.getPlanId());
        StopWatch stopWatch = new StopWatch();
        stopWatch.start();
        try {
            handle(statRequest);
        }catch (Exception e){
            log.error("SalesPlanStatServiceImpl_SalesPlanStat_occar_exception." + taskName() + "Exception:",e);
        }finally {
            if (latch != null) {
                latch.countDown();
            }
        }
        stopWatch.stop();
        log.info("SalesPlanStatAbstract." + taskName() + ".end elapsed time:" + stopWatch.getTotalTimeMillis() + "ms");
    }

    /**
     * 处理任务
     *
     * @param statRequest
     */
    protected abstract void handle(SalesPlanStatRequest statRequest);

    /**
     * 获取任务名称
     *
     * @return
     */
    protected abstract String taskName();


    /**
     * 设置汇总记录合同信息
     *
     * @param statSDO
     * @param monthContract
     */
    public void setStatContractInfo(SalesPlanStatSDO statSDO, MonthContractAndRollingCountResponse monthContract) {
        statSDO.setMonthContractCount(Objects.isNull(monthContract) ? 0 : monthContract.getMonthContractCount());
        statSDO.setBeforeMonthContractMoney(Objects.isNull(monthContract) ? 0L : monthContract.getBeforeMonthContractMoney());
        statSDO.setMonthContractMoney(Objects.isNull(monthContract) ? 0L : monthContract.getMonthContractMoney());
    }

    public void calculateSatisfaction(Integer status, SalesPlanStatSDO salesPlanStat) {
        SalesPlanStatusEnum match = SalesPlanStatusEnum.match(status);
        salesPlanStat.setStatus(status);
        switch (match) {
            case TO_BE_LOCKED:
            case TO_BE_SYNC:
            case TO_BE_REPLIED:
            case TO_BE_PUBLISHED:
                salesPlanStat.calculatePlanSatisfaction();
                break;
            case PUBLISHED:
                salesPlanStat.calculateTaskSatisfaction();
                break;
            case ADJUST:
                salesPlanStat.calculateAdjustSatisfaction();
                break;
            default:
                break;
        }
    }
}
